package com.fdb.efp.nls.service.impl.dw;

import com.alibaba.fastjson.JSONObject;
import com.fdb.basic.framework.core.base.FrameworkService;
import com.fdb.basic.framework.core.constant.MonAlrmLvlEnums.MonAlrmLvlEnum;
import com.fdb.basic.framework.core.exception.ESBException;
import com.fdb.basic.framework.core.util.*;
import com.fdb.efp.nls.service.vo.CfcaSignInfoVO;
import com.fdb.efp.nls.service.vo.LogErrorInfoVO;
import com.fdb.efp.nls.service.facade.CfcaSignInfoService;
import com.fdb.efp.nls.service.facade.ElectronicSignPolyService;
import com.fdb.efp.nls.service.facade.LogErrorInfoService;
import com.fdb.efp.esb.common.constant.ElectronicSignatureConstant;
import com.fdb.efp.esb.common.constant.ElectronicSignatureEnums;
import com.fdb.efp.esb.service.bo.req.dzqz.ReqElectronicSignature3203Bean;
import com.fdb.efp.esb.service.bo.req.dzqz.ReqElectronicSignatureDL01Bean;
import com.fdb.efp.esb.service.bo.resp.dzqz.RspElectronicSignature3203Bean;
import com.fdb.efp.esb.service.bo.resp.dzqz.RspElectronicSignatureDL01Bean;
import com.fdb.efp.esb.service.bo.resp.dzqz.info.ElectronicSignature3203Signatory;
import com.fdb.efp.esb.service.facade.dzqz.ElectronicSignatureService;
import com.fdb.efp.nls.service.vo.BdLoanpayVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 
 * @description:电子签章整合
 * @date:2018年12月25日 上午11:04:07
 * @author:ludayong
 */
@Service("dwElectronicSignPolyService")
public class DwElectronicSignPolyServiceImpl implements FrameworkService, ElectronicSignPolyService {

	private static Logger logger = LoggerFactory.getLogger(DwElectronicSignPolyServiceImpl.class);

	// 电子签章原子服务
	@Autowired
	@Qualifier("electronicSignatureService")
	private ElectronicSignatureService electronicSignatureService;

	// CFCA签署信息
	@Autowired
	@Qualifier("cfcaSignInfoService")
	private CfcaSignInfoService cfcaSignInfoService;

	// 异常信息表
	@Autowired
	@Qualifier("logErrorInfoService")
	private LogErrorInfoService logErrorInfoService;

	/** 第一个签署人序号 */
	private final int THE_FIRST_SIGN_INFO = 0;

	/**
	 * 
	 * @description:电子签章处理
	 * @param param
	 * @return
	 * @date:2018年12月15日 上午11:00:47
	 * @author:ludayong,caoxin 0.2设置CFCA签署状态和签署信息 改为获取响应报文的个人签署信息数组中第一个值
	 * @throws ESBException
	 */
	public boolean handleElectronicSignPoly(Map<String, Object> param) throws ESBException {
		boolean result = false;
		// 返回代码
		String retCode = null;
		// 交易代码（接口代码）
		String tranCode = (String) param.get("tranCode");
		// 开户标识
		String opnFlg = (String) param.get("opnFlg");
		// 订单号
		String orderId = (String) param.get("orderId");
		// 放款申请信息
		BdLoanpayVO bdLoanpayVO = (BdLoanpayVO) param.get("bdLoanpayVO");

		// 当前时间
		String currentTime = DateTool.getCurrentDateTime();
		LogErrorInfoVO logErrorInfoVo = new LogErrorInfoVO();
		// 申请流水号
		logErrorInfoVo.setApplySeq(orderId);
		// 主键
		logErrorInfoVo.setSerno(UUIDUtil.getUUID());
		// 未处理
		logErrorInfoVo.setState(ElectronicSignatureEnums.YesNoEnum.NO.VALUE);
		// 创建时间
		logErrorInfoVo.setCreateTime(currentTime);
		// 最后修改时间
		logErrorInfoVo.setLastModifyTime(currentTime);

		// 上传合同3203请求信息
		ReqElectronicSignature3203Bean req3203Bean = (ReqElectronicSignature3203Bean) param.get("req3203Bean");
		// 合同下载DL01请求信息
		ReqElectronicSignatureDL01Bean reqCADL01Bean = (ReqElectronicSignatureDL01Bean) param.get("reqCADL01Bean");

		// 百度合同签章
		if (!ElectronicSignatureEnums.YesNoEnum.YES.VALUE.equals(opnFlg)) {
			retCode = ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE;
		}

		// 通过合同号查询是否已完成签署，如有则下载合同，创建或上传合同签署：合同编号
		String contractNo = null;

		CfcaSignInfoVO inCfcaSignInfoVO = new CfcaSignInfoVO();
		// 订单号
		inCfcaSignInfoVO.setApplySeq(orderId);
		// 根据申请流水号查询安心签签署信息
		CfcaSignInfoVO queryCfcaSignInfoVO = cfcaSignInfoService.queryByPk(inCfcaSignInfoVO);

		// 是否需要签署合同
		boolean signFlg = true;
		// 当前合同已经签署成功，直接下载对应的合同
		if (!Objects.isNull(queryCfcaSignInfoVO) && ElectronicSignatureEnums.CfcaContractStateEnum.CHANGE_FINISHED.getEnname()
				.equals(queryCfcaSignInfoVO.getCfcaSignState())) {
			signFlg = false;
			// 合同签署：合同编号
			contractNo = queryCfcaSignInfoVO.getCfcaContNo();
			// 合同下载：合同编号
			reqCADL01Bean.setContrNo(contractNo);
		}
		// 上传合同签署
		if (signFlg && ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(retCode)
				&& ElectronicSignatureConstant.TRAN_CODE_3203.equals(tranCode)) {
			// 合同文件路径
			String imageFilePath2 = (String) param.get("imageFilePath");
			// 合同转base64字符
			String contrFlStrm = contractFileToStrByte(imageFilePath2);
			// 转换成功
			if (!StringUtil.isNullorBank(contrFlStrm)) {
				req3203Bean.setContrFlStrm(contrFlStrm);
			}

			RspElectronicSignature3203Bean rsp3203Bean = null;
			try {
				// 电子签章处理：上传合同签署
				rsp3203Bean = electronicSignatureService.electronicSignatureSignUpContract(req3203Bean);
			} catch (Exception e) {
				// 异常信息
				logErrorInfoVo.setErrorMsg(e.getMessage());
				// 备注
				logErrorInfoVo.setRemark("电子签章处理上传合同签署出现异常！");
				// 错误级别
				logErrorInfoVo.setErrorType(MonAlrmLvlEnum.SERIOUS.getEnname());
				// 主键
				logErrorInfoVo.setSerno(UUIDUtil.getUUID());
				// 记录异常信息
				logErrorInfoService.insertLogErrorInfo(logErrorInfoVo);
				throw new ESBException("电子签章处理上传合同签署出现异常：" + e.getMessage());
			}

			// 上传合同签署
			if (ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(rsp3203Bean.getRetStCd())) {
				// 上传合同签署响应码
				retCode = rsp3203Bean.getRetStCd();
				// 上传合同签署：合同编号
				contractNo = rsp3203Bean.getContract().getContrNo();
				// 合同下载：合同编号
				reqCADL01Bean.setContrNo(contractNo);
				// 贷款合同号
				inCfcaSignInfoVO.setContNo(orderId);

				// 安心签合同号
				inCfcaSignInfoVO.setCfcaContNo(rsp3203Bean.getContract().getContrNo());
				// 获取签署人信息数组
				List<ElectronicSignature3203Signatory> signInfoArry = rsp3203Bean.getContract().getContractSignInfArry();
				ElectronicSignature3203Signatory signInfo = Objects.isNull(signInfoArry) ? null : signInfoArry.get(THE_FIRST_SIGN_INFO);
				// caoxin:cfca签署状态
				inCfcaSignInfoVO.setCfcaSignState(Objects.isNull(signInfo) ? "" : signInfo.getSignSt());
				// caoxin:cfca签署时间
				try {
					inCfcaSignInfoVO.setCfcaSignTime(
							Objects.isNull(signInfo) ? "" : DateTool.getDateTimeStr(DateTool.parseDateTime(signInfo.getSignTm())));
				} catch (ParseException e) {
					inCfcaSignInfoVO.setCfcaSignTime(Objects.isNull(signInfo) ? "" : signInfo.getSignTm());
				}
				// 产品id
				// inCfcaSignInfoVO.setPrdId(bdLoanpayVO.getPrdId());
				// 产品代码
				// inCfcaSignInfoVO.setPrdCode(bdLoanpayVO.getPrdCode());
				// 产品名称
				// inCfcaSignInfoVO.setPrdName(bdLoanpayVO.getPrdName());
				// 客户号
				// inCfcaSignInfoVO.setCusId(bdLoanpayVO.getCusId());
				// 客户名称
				inCfcaSignInfoVO.setCusName(bdLoanpayVO.getCusName());

				logger.info("电子签章操作保存安心签数据信息：" + JSONObject.toJSONString(inCfcaSignInfoVO));
				CfcaSignInfoVO cfcaSignInfoDetailVO = cfcaSignInfoService.queryByPk(inCfcaSignInfoVO);
				int num = 0;
				if (cfcaSignInfoDetailVO != null) {
					num = cfcaSignInfoService.updateByPk(inCfcaSignInfoVO);
				} else {
					num = cfcaSignInfoService.insertCfcaSignInfo(inCfcaSignInfoVO);
				}
				logger.info("电子签章操作保存安心签数据数目：" + JSONObject.toJSONString(num));
			} else {
				// 异常信息
				logErrorInfoVo.setErrorMsg(rsp3203Bean.getRtnMsg());
				// 备注
				logErrorInfoVo.setRemark("电子签章处理上传合同签署出现异常！");
				// 错误级别
				logErrorInfoVo.setErrorType(MonAlrmLvlEnum.SERIOUS.getEnname());
				// 主键
				logErrorInfoVo.setSerno(UUIDUtil.getUUID());
				// 记录异常信息
				logErrorInfoService.insertLogErrorInfo(logErrorInfoVo);
				// 上传合同签署信息响应码
				retCode = ElectronicSignatureEnums.RetCodeEnum.FAILURE.VALUE;
				// 上传合同签署异常信息
				logger.error("上传合同签署出错，异常信息：" + rsp3203Bean.getRtnMsg());
				throw new ESBException("上传合同签署出错，异常信息：" + rsp3203Bean.getRtnMsg());
			}
		}

		if (ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(retCode)) {
			RspElectronicSignatureDL01Bean rspDL01Bean = null;
			try {
				// 电子签章处理：合同下载
				rspDL01Bean = electronicSignatureService.electronicSignatureDownloadContract(reqCADL01Bean);
			} catch (Exception e) {
				// 异常信息
				logErrorInfoVo.setErrorMsg(e.getMessage());
				// 备注
				logErrorInfoVo.setRemark("电子签章处理合同下载出现异常！");
				// 错误级别
				logErrorInfoVo.setErrorType(MonAlrmLvlEnum.SERIOUS.getEnname());
				// 记录异常信息
				logErrorInfoService.insertLogErrorInfo(logErrorInfoVo);
				throw new ESBException("电子签章处理合同下载出现异常：" + e.getMessage());
			}

			// 下载合同成功
			if (ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(rspDL01Bean.getRetStCd())) {
				// 上传合同签署响应码
				retCode = rspDL01Bean.getRetStCd();
				// 文件路径
				String conFilePath = (String) param.get("conFilePath");
				// 文件名
				String imageFileName = (String) param.get("imageFileName");
				logger.info("电子签章处理合同下载成功.....");
				// 保存合同
				boolean saveResult = strBytesToFileToContractFile(rspDL01Bean.getContrFlStrm(), conFilePath, imageFileName);
				logger.info("保存签章合同，目标路径：" + conFilePath + imageFileName + "，结果[" + saveResult + "]");
			} else {
				// 异常信息
				logErrorInfoVo.setErrorMsg(rspDL01Bean.getRtnMsg());
				// 备注
				logErrorInfoVo.setRemark("电子签章处理下载合同出现异常！");
				// 错误级别
				logErrorInfoVo.setErrorType(MonAlrmLvlEnum.SERIOUS.getEnname());
				// 主键
				logErrorInfoVo.setSerno(UUIDUtil.getUUID());
				// 记录异常信息
				logErrorInfoService.insertLogErrorInfo(logErrorInfoVo);
				// 下载合同签署信息响应码
				retCode = ElectronicSignatureEnums.RetCodeEnum.FAILURE.VALUE;
				// 下载合同签署异常信息
				logger.error("电子签章处理下载合同出现异常，异常信息：" + rspDL01Bean.getRtnMsg());
			}
		}
		if (ElectronicSignatureEnums.RetCodeEnum.SUCCESS.VALUE.equals(retCode)) {
			result = true;
		} else {
			result = false;
		}
		return result;
	}

	/**
	 * 
	 * 1、并把合同文件转为二进制字符串<br>
	 * 
	 * @param filePath
	 * @param fileName
	 * @return
	 * @date:2018年12月15日 上午11:02:36
	 * @author:ludayong
	 */

	private String contractFileToStrByte(String filePath) {
		File file = new File(filePath);
		String fileStr = null;
		byte[] fileBytes = null;
		try {
			fileBytes = FileUtil.toByteArray(file);
		} catch (IOException e) {
			logger.error("合同文件转字节数组出现异常，异常信息" + e.getMessage());
			e.printStackTrace();
		}
		fileStr = Base64.encodeBytes(fileBytes);
		return fileStr;
	}

	/**
	 * 
	 * 1、把二进制文件字符串转为文件<br>
	 * 
	 * @param fileBinStr
	 * @param fileName
	 * @return
	 * @date:2018年12月15日 上午11:02:36
	 * @author:ludayong
	 */

	private boolean strBytesToFileToContractFile(String fileBytStr, String filePath, String fileName) {
		boolean result = false;
		try {
			byte[] newBytes = Base64.decode(fileBytStr);
			FileUtil.writeBytesToFile(newBytes, filePath, fileName);
			result = true;
		} catch (IOException e) {
			logger.error("字节数组转合同文件出现异常，异常信息" + e.getMessage());
			e.printStackTrace();
		}
		return result;
	}
}
